package edu.uba.fcen.estimacion.estimacion;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.math.stat.descriptive.DescriptiveStatistics;
import org.apache.log4j.Logger;

public class TestOverCiao {

	private static final Logger logger = Logger.getLogger(TestOverCiao.class);
	//Estos valores fueron calculados previamente
	private static double meanOfAgrado = 0d;
//	private static double meanOfAgrado = 2.294903606985144d;
//	private static double stdevOfAgrado = 0.07204921315260468d;
	private static double totalNo = 0;
	private static double totalYes = 0;
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		String pathToCSV = args[0];
		String pathToCiaoDirectory = args[1];
		
		File directoryBase = new File(pathToCiaoDirectory);
		Estimacion estimacion = new Estimacion(pathToCSV);
		
		double twentyPercentToGuess = 0d;
		double totalFiles = 0d;
		totalFiles = calculateTotalFiles(directoryBase);
		twentyPercentToGuess = 20d;
		double[] intervalToGuess = {0,twentyPercentToGuess};
		
		for (int i=1; i<=5; i++){
			meanOfAgrado = trainning(directoryBase, estimacion, intervalToGuess, totalFiles);
			guess(directoryBase, estimacion, intervalToGuess, totalFiles);
			intervalToGuess[0] =  intervalToGuess[0] + 20d;
			intervalToGuess[1] = intervalToGuess[1] + 20d;
		}
	}
	
	private static void guess(File directoryBase, Estimacion estimacion,
			double[] intervalToGuess, double totalFiles) {
		DescriptiveStatistics meanCoverage = new DescriptiveStatistics();
		
		EstimacionData data;
		Means mean;
		double yesHits = 0;
		double totalOpinions = 0;
		double totalNo = 0;
		double totalYes = 0;
		double noHits = 0;
		
		for(File directory : directoryBase.listFiles()) {
			if (directory.isDirectory()) {
				logger.info("processing directory: " + directory.getName());
				for(File in : directory.listFiles()) {
					if (in.getName().endsWith(".freeling")) {
						if(isIntervalGuess(totalFiles, totalOpinions, intervalToGuess)) {
							data = estimacion.runOver(in.getAbsolutePath());
							mean = data.getMeans();
							Double valueStdev = Double.valueOf(mean.getStdevAgrado());
							Double valueMean = Double.valueOf(mean.getMeanAgrado());
							if (valueStdev.isNaN() || valueMean.isNaN()) {
								System.out.println("Es NaN: " + in.getAbsolutePath());
							}
							
							if (in.getName().startsWith("yes")) {
								if (mean.getMeanAgrado() >= meanOfAgrado) {
									yesHits++;
								}
								totalYes++;
							}
							
							if (in.getName().startsWith("no")) {
								if (mean.getMeanAgrado() < meanOfAgrado) {
									noHits++;
								}
								totalNo++;
							} 
							meanCoverage.addValue(data.getCoverage());
						}
						totalOpinions++;
					}
				}
			}
		}
		System.out.println("Guessing");
		System.out.println("Yes hits num.: " + yesHits);
		System.out.println("No hits num.: " + noHits);
		System.out.println("Total Opinions: " + totalOpinions);
		System.out.println("Yes hits %: " + ((double) (yesHits/totalYes)*100));
		System.out.println("No hits %: " + ((double) (noHits/totalNo)*100));
		System.out.println("Mean Coverage: " + meanCoverage.getMean() * 100);
		
	}

	private static double trainning(File directoryBase, Estimacion estimacion, double[] intervalToGuess, double totalFiles) {
		DescriptiveStatistics meanStatistics = new DescriptiveStatistics();
		DescriptiveStatistics stdevStatistics = new DescriptiveStatistics();
		DescriptiveStatistics meanCoverage = new DescriptiveStatistics();
		
		EstimacionData data;
		Means mean;
		double totalOpinions = 0;
		
		for(File directory : directoryBase.listFiles()) {
			if (directory.isDirectory()) {
				logger.info("processing directory: " + directory.getName());
				for(File in : directory.listFiles()) {
					if (in.getName().endsWith(".freeling")){
						if (isIntervalTrainning(totalFiles, totalOpinions, intervalToGuess)) {
							data = estimacion.runOver(in.getAbsolutePath());
							mean = data.getMeans();
							Double valueStdev = Double.valueOf(mean.getStdevAgrado());
							Double valueMean = Double.valueOf(mean.getMeanAgrado());
							if (valueStdev.isNaN() || valueMean.isNaN()) {
								System.out.println("Es NaN: " + in.getAbsolutePath());
							} else {
								meanStatistics.addValue(mean.getMeanAgrado());
								stdevStatistics.addValue(mean.getStdevAgrado());
								meanCoverage.addValue(data.getCoverage());
							}
						}
						totalOpinions++;
					}
				}
			}
		}
		return meanStatistics.getMean();
	}

	private static boolean isIntervalTrainning(double totalFiles, double totalOpinions, double[] intervalToGuess) {
		return !isIntervalGuess(totalFiles, totalOpinions, intervalToGuess);
	}

	private static boolean isIntervalGuess(double totalFiles, double totalOpinions, double[] intervalToGuess) {
		double beginInterval = (intervalToGuess[0]*totalFiles) / 100;
		double endInterval = (intervalToGuess[1]*totalFiles) / 100;
		return totalOpinions >= beginInterval && totalOpinions < endInterval;
	}

	private static double calculateTotalFiles(File directoryBase) {
		double total = 0d;
		for(File directory : directoryBase.listFiles()) {
			if (directory.isDirectory()) {
				for(File in : directory.listFiles()) {
					if (in.getName().endsWith(".freeling")) {
						total++;
						if(in.getName().startsWith("yes")) {
							totalYes++;
						}
						if(in.getName().startsWith("no")) {
							totalNo++;
						}
					}
				}
			}
		}
		return total;
	}

}
